﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using log4net;

namespace StockFinder.Services.Brokers
{
    public class IBDStockListBroker
    {
        private static readonly ILog _Log = LogManager.GetLogger(typeof(IBDStockListBroker));

        public IBDStockListBroker()
        {

        }

        /// <summary>
        /// Updates the stock list with the given stocks
        /// </summary>
        /// <param name="stocks"></param>
        /// <param name="stockListId"></param>
        public void UpdateStockList(List<string> stocks, long stockListId, string listName)
        {
            string editStockListUrl = string.Format("http://www.investors.com/MyIBD/EditPortfolio.aspx?id={0}&action=edit", stockListId);

            //login and get cookies
            #region Login to get cookies

            HttpWebRequest webRequest;
            HttpWebResponse webResponse;
            string pageSource = string.Empty;
            CookieContainer cookieContainer = new CookieContainer();

            string loginUrl = "http://www.investors.com/Services/SiteAjaxService.asmx/MemberSingIn?strEmail=ssattin@gmail.com&strPassword=dennis10&blnRemember=false";

            webRequest = (HttpWebRequest)(WebRequest.Create(loginUrl));
            webRequest.CookieContainer = cookieContainer;
            webRequest.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, #/#";
            webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            webRequest.KeepAlive = true;
            webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            webRequest.Method = "GET";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webResponse = (HttpWebResponse)webRequest.GetResponse();

            //get the response details
            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
            {
                //get the page response
                pageSource = streamReader.ReadToEnd();

                //write the response to diagnostic file
                using (StreamWriter writer = new StreamWriter(new FileStream("testlogin.xml", FileMode.Create)))
                {
                    writer.Write(pageSource);
                }
            }

            webResponse.Close();

            #endregion

            #region Request edit page to get server variables
            //make GET to the edit page to get viewstate
            webRequest = (HttpWebRequest)(WebRequest.Create(editStockListUrl));
            webRequest.CookieContainer = cookieContainer;
            webRequest.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, #/#";
            webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            webRequest.KeepAlive = true;
            webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            webRequest.Method = "GET";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webResponse = (HttpWebResponse)webRequest.GetResponse();

            //get the response details
            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
            {
                //get the page response
                pageSource = streamReader.ReadToEnd();
            }

            webResponse.Close(); 
            #endregion

            #region Build post data variables

            //get server variables required for POST
            string viewStateServerVariable = GetSeverSideVariableByToken(pageSource, "VIEWSTATE");

            //HTML encode
            viewStateServerVariable = HttpUtility.UrlEncode(viewStateServerVariable);

            //generate post data
            StringBuilder postDataStringBuilder = new StringBuilder();            
            postDataStringBuilder.Append("&__EVENTTARGET=");
            postDataStringBuilder.Append("&__EVENTARGUMENT=");
            postDataStringBuilder.Append("&__VIEWSTATE=" + viewStateServerVariable);

            postDataStringBuilder.Append("&ctl00%24ctl00%24SiteScriptManager=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24PredictiveSearchBox%24predictiveSearchBox=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24PredictiveSearchBox%24radioBtnList=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24PredictiveSearchBox%24webMethodParam=");
            postDataStringBuilder.Append(string.Format("&ctl00%24ctl00%24secondaryContent%24leftContent%24txtListName={0}",listName));
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24leftContent%24btnSave=Save");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksUp%24ctl01%24hdPrice=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksUp%24ctl01%24hdPrice0=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksUp%24ctl02%24hdPrice=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksUp%24ctl02%24hdPrice0=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksUp%24ctl03%24hdPrice=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksUp%24ctl03%24hdPrice0=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksDown%24ctl01%24hdPrice=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksDown%24ctl01%24hdPrice0=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksDown%24ctl02%24hdPrice=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksDown%24ctl02%24hdPrice0=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksDown%24ctl03%24hdPrice=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24personal%24MostActiveStocks%24MyStocksDown%24ctl03%24hdPrice0=");
            postDataStringBuilder.Append("&htmMvAll=all");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24PredictiveSearchFooter%24predictiveSearchBox2=");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24PredictiveSearchFooter%24radioBtnList2=GetStockSearchSuggestions");
            postDataStringBuilder.Append("&ctl00%24ctl00%24secondaryContent%24PredictiveSearchFooter%24webMethodParam=");
            postDataStringBuilder.Append("&hiddenInputToUpdateATBuffer_CommonToolkitScripts=1");

            var stockList = string.Empty;
            stocks.ForEach(s => stockList += s + " ");

            if (!string.IsNullOrEmpty(stockList))
            {
                stockList = stockList.Remove(stockList.Length - 1);
            }

            _Log.DebugFormat("IBD Stock List '{0}' updated with '{1}'", listName, stockList);

            postDataStringBuilder.Append(string.Format("&ctl00%24ctl00%24secondaryContent%24leftContent%24txtStocks={0}", stockList));

            #endregion

            #region Send Edit stock list Post

            Byte[] postData = Encoding.UTF8.GetBytes(postDataStringBuilder.ToString());
            webRequest = (HttpWebRequest)(WebRequest.Create(editStockListUrl));
            webRequest.CookieContainer = cookieContainer;
            webRequest.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, #/#";
            webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            webRequest.KeepAlive = true;
            webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = postData.Length;

            //write the data to the stream
            Stream requestStream = webRequest.GetRequestStream();
            requestStream.Write(postData, 0, postData.Length);
            requestStream.Close();
            webResponse = (HttpWebResponse)webRequest.GetResponse();

            //get the response details
            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
            {
                //get the page response
                //pageSource = HttpUtility.HtmlEncode(streamReader.ReadToEnd());
                pageSource = (streamReader.ReadToEnd());
            }
            
            webResponse.Close();

            #endregion
        }

        private static string GetSeverSideVariableByToken(string textToSearch, string token)
        {
            string searchStringStart = string.Format("id=\"__{0}\" value=\"", token);
            const string searchStringEnd = "\" />";

            int startIndex = textToSearch.IndexOf(searchStringStart) + searchStringStart.Length;
            int endIndex = textToSearch.Remove(0, startIndex).IndexOf(searchStringEnd);

            return textToSearch.Substring(startIndex, endIndex);
        }
    }
}
